﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

#if ExcelByStream

namespace Library.Excel
{
    /// <summary>
    /// 引用 ICSharpCode.SharpZipLib.dll
    /// 引用 System.Data.dll
    /// </summary>
    public class ExcelByStream : ExcelByBase
    {
        /// <summary>
        /// https://www.cnblogs.com/Sandon/p/5175829.html
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="vals"></param>
        public static void ExportToExcel(string fileName, DataTable vals)
        {
            fileName = Path.ChangeExtension(fileName, ".xls");
            foreach (var item in ExportExcelByMemoryStream(vals))
            {
                File.WriteAllBytes(fileName, item);
            }
        }

        public static void ExportToOneExcel(string fileName, List<DataTable> list)
        {
            fileName = Path.ChangeExtension(fileName, ".xls");
            foreach (var table in list)
            {
                foreach (var item in ExportExcelByMemoryStream(table))
                {
                    File.WriteAllBytes(fileName, item);
                }
            }
        }

        public static IEnumerable<byte[]> ConvertToByteArray(DataTable dt)
        {
            dt.RemotingFormat = SerializationFormat.Binary; //指定DataSet串行化格式是二进制
            using (MemoryStream ms = new MemoryStream())//定义内存流对象，用来存放DataSet序列化后的值
            {
                IFormatter IF = new BinaryFormatter();//产生二进制序列化格式
                IF.Serialize(ms, dt);//串行化到内存中
                yield return ms.ToArray(); // 将DataSet转化成byte[]
            }
        }

        private static IEnumerable<byte[]> ExportExcelByMemoryStream(DataTable dt)
        {
            //return ConvertToByteArray(dt);

            using (MemoryStream ms = new MemoryStream())//创建一个内存流
            using (StreamWriter sw = new StreamWriter(ms, Encoding.GetEncoding("GB2312")))//以指定的字符编码向指定的流写入字符
            {
                StringBuilder sb = new StringBuilder();

                //写入标题
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    sb.Append(dt.Columns[i].ColumnName + "\t");
                }
                //加入换行字符串
                sb.Append(Environment.NewLine);

                //写入内容
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        sb.Append(dt.Rows[i][j] + "\t");
                    }
                    sb.Append(Environment.NewLine);
                }

                sw.Write(sb.ToString());
                sw.Flush();

                yield return ms.ToArray(); //转换为字节数组
            }
        }
    }
}
#endif